package org.zkoss.zktc.core;

import java.util.List;
import java.util.Properties;
import java.util.Map.Entry;

import org.openqa.selenium.WebElement;
import org.zkoss.zktc.core.DriverLoader;
import org.zkoss.zktc.core.widget.Widget;
import org.zkoss.zktc.core.widget.WidgetDriver;

public class GenericTestCase {

	protected static Properties config;
	
	private static WidgetDriver driver;
	protected static String baseUrl;
//	protected static String browser;
	private static boolean sharedDriver;
	private static boolean closeBrowser;
	
	static ThreadLocal<WidgetDriver> sharedDriverTL = new ThreadLocal<WidgetDriver>();
	
//	private static WebDriver newDriver() {
//		return DriverLoader.loadWebDriver(config);
//	}
	
	protected static WidgetDriver getDriver(){
		return getDriver(false);
	}
	
	protected static WidgetDriver getDriver(boolean clean){
		if(driver==null && sharedDriver){
			driver = sharedDriverTL.get();
		}
		
		if(driver==null){
			driver = DriverLoader.loadWidgetDrvier(config);
		}else if(clean){
			driver.quit();
			driver = DriverLoader.loadWidgetDrvier(config);
		}
		
		sharedDriverTL.set(driver);
		
		return driver;
	}
	
	protected String getTestCaseUrl(String relative){
		return baseUrl+relative;
	}
	
	protected String getTestCaseUrl(){
		return baseUrl;
	}
	
	protected Widget findWidget(String selector){
		return getDriver().findWidget(selector);
	}
	protected Widget findWidget(String selector,boolean strict){
		return getDriver().findWidget(selector,strict);
	}
	protected Widget findWidget(String selector, long timeout){
		return getDriver().findWidget(selector,timeout);
	}
	protected Widget findWidget(String selector,boolean strict,long timeout){
		return getDriver().findWidget(selector,strict,timeout);
	}
	
	protected void waitForTrip(int trip, long timeout){
		getDriver().waitForTrip(trip, timeout);
	}
	protected void waitForReady(long timeout){
		getDriver().waitForReady(timeout);
	}
	protected void waitForReady(){
		getDriver().waitForReady();
	}
	
	protected List<Widget> findWidgets(String selector){
		return getDriver().findWidgets(selector);
	}
	protected List<Widget> findWidgets(String selector,boolean strict){
		return getDriver().findWidgets(selector, strict);
	}
	protected List<Widget> findWidgets(String selector,boolean strict,long timeout){
		return getDriver().findWidgets(selector, strict, timeout);
	}
	
	protected void navigate(String url){
		getDriver().navigate(url);
	}
	
	protected WebElement findElement(String selector){
		return getDriver().findElement(selector);
	}
	protected WebElement findElement(String selector,long timeout){
		return getDriver().findElement(selector, timeout);
	}
	protected List<WebElement> findElements(String selector){
		return getDriver().findElements(selector);
	}
	protected List<WebElement> findElements(String selector,long timeout){
		return getDriver().findElements(selector,timeout);
	}

	protected long getTripId(){
		return getDriver().getTripId();
	}
	
	protected long getTimeout(){
		return getDriver().getTimeout();
	}
	
	static public void beforeClass(){
		String f = System.getProperty("zktc.testcase.config.file");
		if(f!=null){
			config = DriverLoader.loadConfig(f);
		}
		if(config==null){
			config = DriverLoader.loadConfig("zktc-testcase.properties");
		}
		if(config==null){
			throw new IllegalStateException("configuration not found");
		}
		//follow DriverLoader
		final String s = "zktc.system.property.";
		for(Entry e:config.entrySet()){
			String k = e.getKey().toString();
			if(k.startsWith(s) && k.length()>s.length()){
				System.setProperty(k.substring(s.length()),e.getValue().toString());
			}
		}
		//config 
		baseUrl = config.getProperty("testcase.baseUrl");
		sharedDriver = Boolean.parseBoolean(config.getProperty("testcase.sharedDriver","false"));
		closeBrowser = Boolean.parseBoolean(config.getProperty("testcase.closeBrowser","true"));
	}
	
	static public void afterClass(){
		
		if(closeBrowser && !sharedDriver && driver!=null){
			driver.quit();
			driver = null;
		}
	}
	
	public String getConfigProperty(String name){
		return getConfigProperty(name,null);
	}
	public String getConfigProperty(String name,String def){
		return config.getProperty(name,def);
	}
}
